﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Reflection;

namespace WPF.Controls.QuerySelector
{
    public static class EventTrigger
    {
        public static void one(this UIElement element, string eventName, Delegate handler)
        {
            CreateGenericEventHandlerType(element, eventName, handler, typeof(OneEventTriggerBehavior<,>));
        }

        public static void one1(this UIElement element, RoutedEvent routedEvent, Delegate handler)
        {
            CreateGenericEventHandlerType(element, routedEvent, handler, typeof(OneEventTriggerBehavior<,>));
        }

        private static void CreateGenericEventHandlerType(UIElement element, string eventName, Delegate handler, Type genericEventHandlerType)
        {
            var eventInfo = element.GetType().GetEvent(eventName);
            var parameters = eventInfo.EventHandlerType.GetMethod("Invoke").GetParameters();
            var typeParameters = GetTypeParameters(parameters);
            Activator.CreateInstance(genericEventHandlerType.MakeGenericType(typeParameters),
                                            element, eventName, handler);
        }

        private static void CreateGenericEventHandlerType(UIElement element, RoutedEvent routedEvent, Delegate handler, Type genericEventHandlerType)
        {
            
           
            var parameters = routedEvent.HandlerType.GetMethod("Invoke").GetParameters();
            var typeParameters = GetTypeParameters(parameters);
            Activator.CreateInstance(genericEventHandlerType.MakeGenericType(typeParameters),
                                            element, routedEvent, handler);
        }

        private static Type[] GetTypeParameters(ParameterInfo[] parameters)
        {
            if (parameters.Length != 2)
                throw new Exception("The event signature must have two parameters.");
            return new[]
            {
                parameters[0].ParameterType,
                parameters[1].ParameterType,
            };
        }

        public static void bind(this UIElement element)
        {

        }

        public static void unbind(this UIElement element)
        {

        }

        public static void trigger(this UIElement element)
        {

        }
    }
}
